//
//  WmcNetworkRequest.swift
//  YPWatermarkCamera
//
//  Created by 周诗松 on 2022/3/28.
//

import Foundation
import KeychainAccess
import YPNetwork

// MARK: - [WmcNetworkRequest]

class WmcNetworkRequest: YPNetworkRequest {
    // Lifecycle

    required init() {}

    // Internal

    override var host: String {
        var text = "https://wmc.cdzbb.cn"

        let environmentType = YPWmcManager.shared.environmentType

        if environmentType == .develop || environmentType == .test {
            text = "http://wmc.superinyang.com"
        } else if environmentType == .pre_release {
            text = "http://wmc-release.superinyang.com"
        }

        return text
    }

    override var clientInfo: [String: String] {
        return WmcNetworkField.clientInfo
    }

    override var userInfo: [String: String] {
        var result: [String: String] = [:]

        if let yupaoAccountModel = WmcLoginManager.shared.yupaoAccountModel {
            result["uid"] = yupaoAccountModel.userId
            result["uuid"] = yupaoAccountModel.uuid
            result["token"] = yupaoAccountModel.token
            result["singletoken"] = yupaoAccountModel.singleSignToken
            result["userId"] = yupaoAccountModel.userId
            result["userName"] = yupaoAccountModel.username
            result["nickName"] = yupaoAccountModel.nickname
            if let wmcAccountModel = WmcLoginManager.shared.wmcAccountModel {
                result["wmctoken"] = wmcAccountModel.token
            }
        }

        return result
    }

    override var responseField: [YPNetworkRespnseField: String] {
        return [
            .messageField: "msg",
            .codeField: "code",
            .modelField: "data",
            .listField: "list",
        ]
    }

    override var successInterceptor: YPNetworkInterceptor {
        return YPNetworkInterceptor.create(type: .success, code: [0])
    }

    override var loginFailureInterceptor: YPNetworkInterceptor? {
        return YPNetworkInterceptor.create(type: .loginFailure, code: [401]) { (data: Any?, code: Int64, message: String?) in
            WmcLoginManager.logout()
            
            if YPWmcManager.shared.isIndependentPage {
                WmcLoginManager.push(animated: true)
                return
            }
            
            YPWmcManager.shared.delegate.loginDelegate?.loginInvalid(.current, data: data, code: code, message: message)
        }
    }

    override var encryptionParameters: ((Any) -> Any?)? {
        return { parameters in
            if let parameters = parameters as? [String: Any] {
                return WmcEncryption.encode(param: parameters)
            }
            return nil
        }
    }

    override var decryptionParameters: ((Any) -> Any?)? {
        return { data in
            if let dataStr = data as? String {
                return WmcEncryption.decode(dataStr)
            }
            return nil
        }
    }
}

// MARK: - [WmcNetworkField]

class WmcNetworkField {
    // Internal

    static var clientInfo: [String: String] {
        let source = YPWmcManager.shared.platform.info.sourceField
        let appVersion = Self.appVersion
        let deviceName = Self.deviceName
        let uuid = Self.uuid
        let systemVersion = Self.systemVersion

        var business: String = "5"
        if YPWmcManager.shared.platform == .fishBubble {
            business = "1"
        } else if YPWmcManager.shared.platform == .recordWork {
            business = "2"
        }
        
        var header: [String: String] = [
            "x-log-apiversion": "0.6.0",
            "x-log-bodyrawsize": "1234",
            "channel": "AppStore",
            "business": business,
            "apiVersion": "2.0",
            "system": "ios",
            "appSystem": "ios",
            "app_system": "ios",
            "systemType": "ios",
            "system_type": "ios",
            "memberSource": "iOS",
            "member_source": "iOS",
            "version": appVersion,
            "wmcApiVersion": "\(YPWmcManager.shared.version)",
            "device": deviceName,
            "source": source,
            "deviceid": uuid,
            "imei": uuid,
            "systemversion": systemVersion,
            "systemVersion": systemVersion,
            "system_version": systemVersion,
            "deviceuuid": uuid,
            "deviceUuid": uuid,
            "device_uuid": uuid,
        ]
        
        header.merge(YPWmcManager.shared.mediaExtensionHeaders, uniquingKeysWith: {$1})

        return header
    }

    // Private

    private static var systemVersion: String = {
        return UIDevice.current.systemVersion
    }()

    private static var uuid: String = {
        let key = "uuid"
        guard let info = Bundle.main.infoDictionary else { return "" }
        guard let identifier = info["CFBundleIdentifier"] as? String else { return "" }

        let keychain = Keychain(service: identifier)
        guard let uuid = keychain[key] else {
            let uuid: String? = UIDevice.current.identifierForVendor?.uuidString
            keychain[key] = uuid
            return uuid ?? "无UUID"
        }
        return uuid
    }()

    private static var deviceName: String = {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        return identifier
    }()

    private static var appVersion: String {
        let info = Bundle.main.infoDictionary
        return info?["CFBundleShortVersionString"] as? String ?? "Unknown"
    }
}
